package com.zjsru.plan2023.oneday;

import java.util.HashMap;
import java.util.Map;

/**
 * @Author: cookLee
 * @Date: 2023-11-23
 * HTML 实体解析器
 * 双引号：字符实体为 &quot; ，对应的字符是 " 。
 * 单引号：字符实体为 &apos; ，对应的字符是 ' 。
 * 与符号：字符实体为 &amp; ，对应对的字符是 & 。
 * 大于号：字符实体为 &gt; ，对应的字符是 > 。
 * 小于号：字符实体为 &lt; ，对应的字符是 < 。
 * 斜线号：字符实体为 &frasl; ，对应的字符是 / 。
 */
public class EntityParser {

    /**
     * 主
     * \
     * 输入：text = "&amp; is an HTML entity but &ambassador; is not."
     * 输出："& is an HTML entity but &ambassador; is not."
     * 解释：解析器把字符实体 &amp; 用 & 替换
     * \
     * 输入：text = "and I quote: &quot;...&quot;"
     * 输出："and I quote: \"...\""
     * \
     * @param args args
     */
    public static void main(String[] args) {
        EntityParser entityParser = new EntityParser();
        String text = "&amp; is an HTML entity but &ambassador; is not.";
        System.out.println(entityParser.entityParser(text));
    }


    /**
     * 实体解析器
     *
     * @param text 文本
     * @return {@link String}
     */
    public String entityParser(String text) {
        Map<String, String> map = new HashMap<>();
        map.put("&quot;", "\"");
        map.put("&apos;", "'");
        map.put("&amp;", "&");
        map.put("&gt;", ">");
        map.put("&lt;", "<");
        map.put("&frasl;", "/");
        int len = text.length();
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < len; ) {
            if (text.charAt(i) == '&') {
                //定义一个变量获取&开头的特殊字符
                int j = i + 1;
                //获取全部的特殊字符,特殊符号最长的为&frasl 不超过6位
                while (j < len && j - i < 6 && text.charAt(j) != ';') {
                    j++;
                }
                //获取区间内的截断值，Math.min(j + 1, len) 防止超界
                String substring = text.substring(i, Math.min(j + 1, len));
                if (map.containsKey(substring)) {
                    sb.append(map.get(substring));
                    //重新定位
                    i = j + 1;
                    //跳过已替换的值
                    continue;
                }
            }
            //正常添加，同时增加i的值
            sb.append(text.charAt(i++));
        }
        return sb.toString();
    }

}
